home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_07_05
/
v7n5110a.txt
< prev
Wrap
Text File
|
1989-04-15
|
9KB
|
305 lines
Listing 1
/* FFT - Cooley-Tukey Fast Fourier Transform
*
* Purpose: To calculate the discrete Fast
* Fourier Transform (or its inverse)
* of a set of complex data elements.
*
* Setup: COMPLEX data[];
* int n;
* int flag;
* void fft();
*
* Call: fft(data, n, flag);
*
* Where: data is an array of n+1 data
* elements, where data[0] is
* unused.
* n is the number of valid data
* elements in "data" ( i.e. -
* data[1...n] ). It MUST be
* an integer power of two.
* flag is a Boolean flag which
* if zero indicates that the
* inverse Fourier transform is
* to be calculated; otherwise
* the Fourier transform is
* calculated.
*
* Result: The Fourier transform (or the
* inverse Fourier transform) is
* calculated in place and returned
* in "data"; the original data
* elements are overwritten.
*
* Note: The data type COMPLEX is:
*
* typedef struct complex
* {
* float real;
* float imag;
* }
* COMPLEX;
*/
void fft(data, n, flag)
COMPLEX data[];
int n;
int flag;
{
int a, b, c, d, e; /* Counter variables */
COMPLEX temp; /* Swap variable */
COMPLEX u, v; /* Temporary variables */
double theta;
double PI = 3.14159265358979;
/* Perform bit reversal */
theta = flag ? PI : -PI;
b = n/2 + 1;
for (a = 2; a < n; a++)
{
if (a < b)
{
temp.real = data[a].real;
temp.imag = data[a].imag;
data[a].real = data[b].real;
data[a].imag = data[b].imag;
data[b].real = temp.real;
data[b].imag = temp.imag;
}
c = n/2;
while (c < b)
{
b -= c;
c /= 2;
}
b += c;
}
/* Calculate Fourier transform */
c = 1;
while (c < n)
{
d = c;
c *= 2;
u.real = 1.0;
u.imag = 0.0;
v.real = cos(theta/d);
v.imag = sin(theta/d);
for (b = 1; b <= d; b++)
{
for (a = b; a <= n; a += c)
{
e = a + d;
temp.real = data[e].real * u.real -
data[e].imag * u.imag;
temp.imag = data[e].real * u.imag -
data[e].imag * u.real;
data[e].real = data[a].real - temp.real;
data[e].imag = data[a].imag - temp.imag;
data[a].real += temp.real;
data[a].imag += temp.imag;
}
temp.real = u.real;
u.real = u.real * v.real -
u.imag * v.imag;
u.imag = temp.real * w.imag +
u.imag * v.real;
}
}
/* Normalize if not inverse transform */
if (flag)
for (a = 1; a <= n; a++)
{
data[a].real /= n;
data[a].imag /= n;
}
}
Listing 1 - Fast Fourier Transform (Cooley-Tukey)
-------------------------------------------------
Listing 2
/* FWT - Shank's Fast Walsh Transform
*
* Purpose: To calculate the discrete Fast
* Walsh Transform (or its inverse)
* of a set of real data elements.
*
* Setup: float data[];
* int n;
* int flag;
* void fwt();
*
* Call: fwt(data, n, flag);
*
* Where: data is an array of n+1 data
* elements, where data[0] is
* unused.
* n is the number of valid data
* elements in "data" ( i.e. -
* data[1...n] ). It MUST be
* an integer power of two.
* flag is a Boolean flag which
* if zero indicates that the
* inverse Walsh transform is
* to be calculated; otherwise
* the Walsh transform is
* calculated.
*
* Result: The Walsh transform (or the
* inverse Walsh transform) is
* calculated in place and returned
* in "data"; the original data
* elements are overwritten.
*
* Note: The Walsh function coefficients
* returned in data are arranged in
* increasing Paley (dyadic) order.
*/
void fwt(data, n, flag)
float data[];
int n;
int flag;
{
int a, b, c, d, e; /* Counter variables */
double temp; /* Swap variable */
/* Perform bit reversal */
b = n/2 + 1;
for (a = 2; a < n; a++)
{
if (a < b)
{
temp = data[a];
data[a] = data[b];
data[b] = temp;
}
c = n/2;
while (c < b)
{
b -= c;
c /= 2;
}
b += c;
}
/* Calculate Walsh transform */
c = 1;
while (c < n)
{
d = c;
c *= 2;
for (b = 1; b <= d; b++)
for (a = b; a <= n; a += c)
{
e = a + d;
temp = data[e];
data[e] = data[a] - temp;
data[a] += temp;
}
}
/* Normalize if not inverse transform */
if (flag)
for (a = 1; a <= n; a++)
data[a] /= n;
}
Listing 2 - Fast Walsh Transform (Shank)
----------------------------------------
Figure 1
|<-------- ONE PERIOD -------->|
+1 |-------------------------------
WAL(0), PAL(0), CAL(0) 0 +-------------------------------->
-1 |
+1 |--------------+
WAL(1), PAL(1), SAL(1) 0 +--------------|----------------->
-1 | +----------------
+1 |-------+ +-------
WAL(2), PAL(3), CAL(1) 0 +-------|---------------|-------->
-1 | +---------------+
+1 |-------+ +-------+
WAL(3), PAL(2), SAL(2) 0 +-------|-------|-------|-------->
-1 | +-------+ +-------
+1 |---+ +-------+ +---
WAL(4), PAL(6), CAL(2) 0 +---|-------|-------|-------|---->
-1 | +-------+ +-------+
+1 |---+ +---+ +-------+
WAL(5), PAL(7), SAL(3) 0 +---|-------|---|---|-------|---->
-1 | +-------+ +---+ +---
+1 |---+ +---+ +---+ +---
WAL(6), PAL(5), CAL(3) 0 +---|---|---|-------|---|---|---->
-1 | +---+ +-------+ +---+
+1 |---+ +---+ +---+ +---+
WAL(7), PAL(4), SAL(4) 0 +---|---|---|---|---|---|---|---->
-1 | +---+ +---+ +---+ +---
+1 |-+ +---+ +---+ +---+ +-
WAL(8), PAL(12), CAL(4) 0 +-|---|---|---|---|---|---|---|-->
-1 | +---+ +---+ +---+ +---+
+1 |-+ +---+ +-+ +---+ +---+
WAL(9), PAL(13), SAL(5) 0 +-|---|---|---|-|-|---|---|---|-->
-1 | +---+ +---+ +-+ +---+ +-
+1 |-+ +-+ +---+ +---+ +-+ +-
WAL(10), PAL(15), CAL(5) 0 +-|---|-|-|---|---|---|-|-|---|-->
-1 | +---+ +-+ +---+ +-+ +---+
+1 |-+ +-+ +---+ +-+ +-+ +---+
WAL(11), PAL(14), SAL(6) 0 +-|---|-|-|---|-|-|---|-|-|---|-->
-1 | +---+ +-+ +-+ +---+ +-+ +-
+1 |-+ +-+ +-+ +---+ +-+ +-+ +-
WAL(12), PAL(10), CAL(6) 0 +-|-|-|---|-|-|---|-|-|---|-|-|-->
-1 | +-+ +---+ +-+ +-+ +---+ +-+
+1 |-+ +-+ +-+ +-+ +-+ +---+ +-+
WAL(13), PAL(11), SAL(7) 0 +-|-|-|---|-|-|-|-|-|-|---|-|-|-->
-1 | +-+ +---+ +-+ +-+ +-+ +-+ +-
+1 |-+ +-+ +-+ +-+ +-+ +-+ +-+ +-
WAL(14), PAL(9), CAL(7) 0 +-|-|-|-|-|-|-|---|-|-